﻿#region using

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

#endregion

namespace JupiterLibrary
{
    /// <summary>
    /// Un Sprite es un Rectangulo formato por 4 vertices, con posibilidad de color y textura
    /// </summary>
    public class Sprite
    {
        VB vb;

        Rectangle rectangle;

        public Texture2D Texture;

        public Matrix Matrix;

        public bool UseMatrix=false;

        public Sprite()
        {
            Matrix = Matrix.Identity;

            // Create the VertexBuffer object
            vb = Jupiter.Video.VertexBuffers.CreateAndAdd();

            // Assign the position + color + texturecoord

            vb.Position = new Vector3[4];
            
            vb.Color = new Color[4];

            for (int i = 0; i < 4; i++)
                vb.Color[i] = Color.White;
            
            vb.TextureCoord = new Vector2[4];

            vb.TextureCoord[0] = new Vector2(0, 1);
            vb.TextureCoord[1] = new Vector2(0, 0);
            vb.TextureCoord[2] = new Vector2(1, 1);
            vb.TextureCoord[3] = new Vector2(1, 0);

        }

        public void InvertirCoordsTextura(bool invX, bool invY)
        {
            if (invX && invY)
            {
                vb.TextureCoord[0] = new Vector2(1, 0);
                vb.TextureCoord[1] = new Vector2(1, 1);
                vb.TextureCoord[2] = new Vector2(0, 0);
                vb.TextureCoord[3] = new Vector2(0, 1);
                
                return;

            }

            if (invX)
            {
                vb.TextureCoord[0] = new Vector2(1, 1);
                vb.TextureCoord[1] = new Vector2(1, 0);
                vb.TextureCoord[2] = new Vector2(0, 1);
                vb.TextureCoord[3] = new Vector2(0, 0);
            }

            if (invY)
            {
                vb.TextureCoord[0] = new Vector2(0, 0);
                vb.TextureCoord[1] = new Vector2(0, 1);
                vb.TextureCoord[2] = new Vector2(1, 0);
                vb.TextureCoord[3] = new Vector2(1, 1);
            }
        }

        public void SetRectangle(Rectangle rectangle)
        {
            this.rectangle = rectangle;
        }

        public void SetAlpha(float alpha)
        {
            vb.SetAlpha(alpha);
        }

        public void SetColor(Color color)
        {
            vb.SetColor(color);
        }

        public void SetColorWithoutAlpha(Color color)
        {
            vb.SetColorWithoutAlpha(color);
        }

        public void Update()
        {
            Vector3 a, b, c, d;

            if (!UseMatrix)
            {
                a = new Vector3(rectangle.X, rectangle.Top, 0);
                b = new Vector3(rectangle.X, rectangle.Bottom, 0);
                c = new Vector3(rectangle.Right, rectangle.Bottom, 0);
                d = new Vector3(rectangle.Right, rectangle.Top, 0);
            }
            else
            {
                a = new Vector3(0, 0, 0);
                b = new Vector3(0, rectangle.Height, 0);
                c = new Vector3(rectangle.Width, rectangle.Height, 0);
                d = new Vector3(rectangle.Width, 0, 0);


                Vector3 desp= new Vector3(rectangle.Width / 2, rectangle.Height/2, 0);

                a -= desp;
                b -= desp;
                c -= desp;
                d -= desp;
            }

            vb.Position[0] = b;
            vb.Position[1] = a;
            vb.Position[2] = c;
            vb.Position[3] = d;

            // Infor the VB that the values have changed
            vb.Dirty = true;
        }

        public void DrawEffect(Color color)
        {

            Jupiter.Video.GraphicsDevice.BlendState = BlendState.Additive;

            SetColor(color);
            Update();

            Draw();

            Jupiter.Video.DrawBeforeSprites();
        }

        public void Draw()
        {
            // Bind the VertexBuffer to the device
            vb.SetToDevice();

            // Access to the basicEffect
            BasicEffect basicEffect = Jupiter.Video.BasicEffect;

            if (UseMatrix)
            {
                basicEffect.World = Matrix;
            }
            else
            {
                basicEffect.World = Matrix.Identity;
            }

            if (Texture == null)
                basicEffect.Texture = null;
            else
                basicEffect.Texture=Texture;

            basicEffect.TextureEnabled = (basicEffect.Texture != null);
        
            // Ya está activado en el método Video.DrawBeforeSprites 
            // basicEffect.VertexColorEnabled = true;

            foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
            {
                pass.Apply();
                Jupiter.Video.GraphicsDevice.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2);
            }

            Jupiter.Video.GraphicsDevice.SetVertexBuffer(null);
            basicEffect.World = Matrix.Identity;
        }

        public void Draw(AlphaTestEffect effect)
        {
            // Bind the VertexBuffer to the device
            vb.SetToDevice();

            if (UseMatrix)
            {
                effect.World = Matrix;
            }
            else
            {
                effect.World = Matrix.Identity;
            }

            if (Texture == null)
                effect.Texture = null;
            else
                effect.Texture = Texture;

            // Ya está activado en el método Video.DrawBeforeSprites 
            // basicEffect.VertexColorEnabled = true;

            foreach (EffectPass pass in effect.CurrentTechnique.Passes)
            {
                pass.Apply();
                Jupiter.Video.GraphicsDevice.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2);
            }

            Jupiter.Video.GraphicsDevice.SetVertexBuffer(null);
            effect.World = Matrix.Identity;
        }
    }
}
